﻿using System.Collections.Generic;
using System.Linq;

namespace Scrabble.Model
{
    public partial class Game
    {
        #region Tile distribution

        struct TileAllocation
        {
            private readonly Tile _sample;
            private readonly int _quantity;

            private TileAllocation(Tile sample, int quanity)
            {
                _sample = sample;
                _quantity = quanity;
            }

            public Tile Tile
            {
                get { return _sample; }
            }

            public int Quantity
            {
                get { return _quantity; }
            }

            public IEnumerable<Tile> Generate
            {
                get
                {
                    var sample = Tile;

                    return Enumerable.Range(0, Quantity).Select(n =>
                        sample.InitiallyBlank ? Tile.Blank : new Tile(sample.Letter, sample.Points));
                }
            }

            public static TileAllocation OfTile(Tile tile, int quantity)
            {
                return new TileAllocation(tile, quantity);
            }
        }

        private static readonly TileAllocation[] TileDistribution = new[]
        {
            TileAllocation.OfTile(new Tile('A', 1),  9),
            TileAllocation.OfTile(new Tile('B', 3),  2),
            TileAllocation.OfTile(new Tile('C', 3),  2),
            TileAllocation.OfTile(new Tile('D', 2),  4),
            TileAllocation.OfTile(new Tile('E', 1), 12),
            TileAllocation.OfTile(new Tile('F', 4),  2),
            TileAllocation.OfTile(new Tile('G', 2),  3),
            TileAllocation.OfTile(new Tile('H', 4),  2),
            TileAllocation.OfTile(new Tile('I', 1),  9),
            TileAllocation.OfTile(new Tile('J', 8),  1),
            TileAllocation.OfTile(new Tile('K', 5),  1),
            TileAllocation.OfTile(new Tile('L', 1),  4),
            TileAllocation.OfTile(new Tile('M', 3),  2),
            TileAllocation.OfTile(new Tile('N', 1),  6),
            TileAllocation.OfTile(new Tile('O', 1),  8),
            TileAllocation.OfTile(new Tile('P', 3),  2),
            TileAllocation.OfTile(new Tile('Q', 10), 1),
            TileAllocation.OfTile(new Tile('R', 1),  6),
            TileAllocation.OfTile(new Tile('S', 1),  4),
            TileAllocation.OfTile(new Tile('T', 1),  6),
            TileAllocation.OfTile(new Tile('U', 1),  4),
            TileAllocation.OfTile(new Tile('V', 4),  2),
            TileAllocation.OfTile(new Tile('W', 4),  2),
            TileAllocation.OfTile(new Tile('X', 8),  1),
            TileAllocation.OfTile(new Tile('Y', 4),  2),
            TileAllocation.OfTile(new Tile('Z', 10), 1),
            TileAllocation.OfTile(Tile.Blank, 2)
        };

        #endregion

        public static Tile[] Tiles
        {
            get { return TileDistribution.SelectMany(series => series.Generate).ToArray(); }
        }
    }
}
